use axum_app_common::{
    error::{parse_db_err_duplicate_err, BizError},
    model::{BizRequest, BizResponse, PageRequest, PageResult},
    service_store, BizHandler, BizHandlerResult, ServiceStore,
};
use axum_app_dao::{
    entity::sys_user,
    user_dal::{self, UserQueryCondition},
    UserQuery, UserStatus,
};
use sea_orm::Order;
use serde_json::json;
use tracing::debug;

use crate::{
    model::user::{
        UserCreateParams, UserQueryPageParams, UserQueryParams, UserQueryResponse,
        UserStatusToggleParams, UserUpdateParams,
    },
    service::{
        role_svc::RoleSvc,
        user_svc::{self, UserSvc},
    },
};

use serde::{Deserialize, Serialize};
use validator::Validate;

pub struct UserHandler;

impl BizHandler for UserHandler {
    fn service_map() -> ServiceStore {
        service_store! {
            ("user.query.page","分页查询用户信息") => query_page ;
            ("user.query.current","查询当前用户信息") => query_current;
            ("user.create","查询当前用户信息") => create_user;
            ("user.update.passwd","查询当前用户信息") => update_user_passwd;
            ("user.query","查询用户信息") => query;
            ("user.update","更新用户信息") => update_user;
            ("user.delete","删除用户信息") => delete_user;
            ("user.status.toggle","切换用户状态") => status_toggle;
            ("user.role.bind","绑定用户角色信息") => role_bind;
            ("user.role.unbind","取消绑定用户角色信息") => role_unbind
        }
    }
}

/**
 * 分页查询用户信息
 */

pub async fn query_page(request: BizRequest) -> BizHandlerResult {
    let context = request.get_context();
    let state = request.get_state().unwrap();

    let params = PageRequest::<UserQueryPageParams>::try_from(request.get_biz_content())?;

    let curr_user = &context.unwrap().current_user;
    debug!("当前用户:{curr_user:?}");

    let params_opt = params.params;

    let db_conn = &state.db_conn;

    let mut cond =
        UserQueryCondition::new(vec![(sys_user::Column::Id, Order::Desc)]).deleted(false);

    if let Some(params) = params_opt {
        cond = cond
            .display_name_left_like(params.display_name.as_deref())
            .username_eq(params.username.as_deref());
    };

    let page_result = UserQuery::query_page(db_conn, params.page_num, params.page_size, cond).await;

    use axum_app_common::model::PageResultTryFrom;
    let res = PageResult::<UserQueryResponse>::try_build_from(page_result)?;

    Ok(BizResponse::success(serde_json::to_value(res).unwrap()))
}

/**
 * 获取当前用户信息
 */
pub async fn query_current(request: BizRequest) -> BizHandlerResult {
    let Some(session) = request.get_context() else {
        return Ok(BizResponse::fail_with_biz_error(
            BizError::InvalidSession,
            None,
        ));
    };

    match &session.current_user {
        Some(user) => Ok(BizResponse::success(user.clone().into())),
        None => Ok(BizResponse::fail_with_biz_error(
            BizError::InvalidSession,
            Some("未查询到当前用户信息"),
        )),
    }
}

/**
 * 创建用户信息
 */
pub async fn create_user(request: BizRequest) -> BizHandlerResult {
    let state = request.get_state();
    let db_conn = &state.unwrap().db_conn;

    let params = request.get_biz_model::<UserCreateParams>()?;

    let res = UserSvc::new(db_conn, None)
        .create(
            &params.username,
            &params.display_name,
            Some(&params.mobile),
            None,
            Some(UserStatus::Inactive),
        )
        .await;

    if let Ok(res) = res {
        let id = res.id.as_ref();
        return Ok(BizResponse::success(json!({"id": id})));
    }

    let err = res.err().unwrap();
    let err = err.root_cause();
    if let Some(_err) = err.downcast_ref::<BizError>() {
        return Ok(BizResponse::fail_with_biz_error_ref(_err, None));
    }

    if let Some(_err) = err.downcast_ref::<sea_orm::RuntimeErr>() {
        // 数据冲突
        if let Some((col, val)) = parse_db_err_duplicate_err(&_err.to_string()) {
            return Ok(BizResponse::fail_with_biz_error(
                BizError::DbDuplicateErr(format!("{}列冲突", col)),
                None,
            ));
        }

        return Ok(BizResponse::fail_with_biz_error(
            BizError::DbErr,
            Some(&_err.to_string()),
        ));
    }

    Ok(BizResponse::fail_with_biz_error(
        BizError::Unknown,
        Some(&err.to_string()),
    ))
}

/**
 * 修改用户信息
 */
pub async fn update_user(request: BizRequest) -> BizHandlerResult {
    let state = request.get_state();

    let params = request.get_biz_model::<UserUpdateParams>()?;

    let svc = user_svc::UserSvc::new(&state.unwrap().db_conn, None);

    let res = svc
        .update_user_by_userid(
            &params.userid,
            params.username,
            params.display_name,
            params.mobile,
        )
        .await?;

    Ok(BizResponse::success(res.into()))
}

/// 用户更新
#[derive(Debug, Deserialize, Validate)]
pub struct UpdateUserPasswdParams {
    #[validate(length(min = 1, message = "用户ID不得为空"))]
    pub userid: String,

    #[validate(length(min = 6, message = "用户ID不得为空"))]
    pub passwd: String,
}
/**
 * 修改用户信息
 */
pub async fn update_user_passwd(request: BizRequest) -> BizHandlerResult {
    let state = request.get_state();

    let params = request.get_biz_model::<UpdateUserPasswdParams>()?;

    let userid = params.userid;
    let passwd = params.passwd;

    let svc = user_svc::UserSvc::new(&state.unwrap().db_conn, None);

    let res = svc.update_user_passwd(&userid,&passwd).await?;

    Ok(BizResponse::success(res.into()))
}

/**
 * 删除用户信息
 */
pub async fn delete_user(request: BizRequest) -> BizHandlerResult {
    let state = request.get_state();

    let params = request.get_biz_model::<UserUpdateParams>()?;

    let svc = user_svc::UserSvc::new(&state.unwrap().db_conn, None);

    let rows = svc.soft_delete_by_userid(&params.userid).await?;

    Ok(BizResponse::success(rows.into()))
}

/**
 * 查询用户信息
 */
pub async fn query(request: BizRequest) -> BizHandlerResult {
    let state = request.get_state();

    let params = request.get_biz_model::<UserQueryParams>()?;

    let id = params.id;

    let q_res = UserQuery::find_user_by_id(&state.unwrap().db_conn, id)
        .await?
        .map(|mut s| {
            s.password = "".to_string();
            s
        });

    let Some(user) = q_res else {
        return Ok(BizResponse::fail_with_biz_error(
            BizError::DataNotFound,
            Some("用户不存在"),
        ));
    };

    let user = TryInto::<UserQueryResponse>::try_into(user)?;

    Ok(BizResponse::success(serde_json::to_value(user).unwrap()))
}

/**
 * 切换用户状态
 */
pub async fn status_toggle(request: BizRequest) -> BizHandlerResult {
    let state = request.get_state();

    let params = request.get_biz_model::<UserStatusToggleParams>()?;

    let svc = user_svc::UserSvc::new(&state.unwrap().db_conn, None);
    let res = svc
        .toggle_user_status_by_userid(&params.userid, &params.action)
        .await?;

    Ok(BizResponse::success(serde_json::to_value(res).unwrap()))
}

#[derive(Debug, Deserialize, Validate)]
struct UserRoleBindParams {
    userid: String,
    role_codes: Vec<String>,
}
/// 资源信息绑定角色关系
pub async fn role_bind(request: BizRequest) -> BizHandlerResult {
    let state = request.get_state().unwrap();
    let ctx = request.get_context();
    let params = request.get_biz_model::<UserRoleBindParams>()?;

    let svc = RoleSvc::new(&state.db_conn, ctx);

    let role_codes: Vec<&str> = params.role_codes.iter().map(|s| s.as_str()).collect();
    let _res = svc.bind_role(&params.userid, role_codes).await?;

    Ok(BizResponse::success(json!({})))
}

/**
 * 解除绑定关系
 */
pub async fn role_unbind(request: BizRequest) -> BizHandlerResult {
    let state = request.get_state().unwrap();
    let ctx = request.get_context();
    let params = request.get_biz_model::<UserRoleBindParams>()?;

    let svc = RoleSvc::new(&state.db_conn, ctx);

    let role_codes: Vec<&str> = params.role_codes.iter().map(|s| s.as_str()).collect();
    let _res = svc.unbind_role(&params.userid, role_codes).await?;

    Ok(BizResponse::success(json!({})))
}
